package cn.kennylee.codehub.springmvc.exceptionhandler;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * <p> MyBatis 异常处理类 </p>
 * <p>Created on 2025/10/14.</p>
 *
 * @author kennylee
 * @since 0.0.1
 */
@RestControllerAdvice
@ConditionalOnClass(name = "org.apache.ibatis.exceptions.TooManyResultsException")
@Slf4j
public class MyBatisExceptionHandler implements Ordered {

    private final ExceptionResultFactory resultFactory;

    public MyBatisExceptionHandler(ExceptionResultFactory resultFactory) {
        this.resultFactory = resultFactory;
    }

    @PostConstruct
    public void init() {
        log.info("MyBatis异常处理类已加载");
    }

    /**
     * 处理MyBatis的TooManyResultsException异常
     * 当selectOne方法期望返回单个结果却找到多个结果时抛出
     */
    @ExceptionHandler(TooManyResultsException.class)
    public ResultModel<Object> handleTooManyResultsException(TooManyResultsException e) {
        log.error("MyBatis查询返回结果过多异常: {}", e.getMessage());
        // 构建清晰的错误信息
        String errorMessage = "数据库查询错误：期望返回单个结果，但查询到多个匹配项。";
        // 添加解决建议到日志
        log.debug("解决建议: 1. 检查查询条件是否足够精确 2. 考虑使用LIMIT 1限制结果 3. 如预期返回多条数据，请使用selectList方法");
        return resultFactory.createFailedResult(ResultErrorCode.SQL_ERROR, errorMessage);
    }

    /**
     * 处理其他MyBatis相关异常
     */
    @ExceptionHandler(org.apache.ibatis.exceptions.PersistenceException.class)
    public ResultModel<Object> handlePersistenceException(org.apache.ibatis.exceptions.PersistenceException e) {
        log.error("MyBatis持久化异常: {}", e.getMessage());
        return resultFactory.createFailedResult(ResultErrorCode.SQL_ERROR, "数据持久化操作失败");
    }

    @Override
    public int getOrder() {
        return 3;
    }
}
